import styled from 'styled-components';
import React, { CSSProperties, useCallback, useEffect, useState } from 'react';
import { Input, Button as AntdButton, Tree, Collapse, Modal, Drawer, Select, Tabs } from 'antd';
import { PlusOutlined, TableOutlined, UnorderedListOutlined, SettingOutlined, DatabaseOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import type { CollapseProps } from 'antd';
import { ConnectorDatabaseType, ConnectorDataSource, DataSource, dataSourceGetDataSources, MetaDataDomain, metaDataGetDomainsByIdentifiers, metaDataGetMetaDataObjects, metaDataGetMetaDatas, metaDataSaveDomain } from '../../../services';
import { DataSourceConfig, DomainImporter, MetaDataObjectPanel, MetaDataDomainPanel, DataDataSourceTable } from '.';
import { dsFind, ComparsionOperator } from '@/services/local';
import { CLASS_CLASS_IDENTIFIER, DATASOURCE_CLASS_IDENTIFIER, DOMAIN_CLASS_IDENTIFIER } from '@/services/constants';
import { TableList } from '@/components';

const { Search } = Input;

export interface DataSourceCategoryTreeProps {
    style?: CSSProperties;
    viewModel?: 'storage' | 'domain' | string;
    dataSource: DataSource | null;
    onDataSourceSelected: (dataSource: DataSource | null) => Promise<void> | void;
    onDomainSelected: (domainIdentifier: string | null) => Promise<void>;
    onSelected: (type: 'root' | 'domain' | 'object' | string, node: any) => Promise<void>;
    onViewModelChange: (type: 'storage' | 'domain' | string) => Promise<void>;
    version: number;
}

export const DataSourceCategoryTree: React.FC<DataSourceCategoryTreeProps> = (props) => {

    const [isModalOpen, setIsModalOpen] = useState(false);

    const [domainMgrOpen, setDomainMgrOpen] = useState<boolean>(false);

    const [data, setData] = useState<Array<DataSource>>([]);

    const [table, setTable] = useState<any>();

    const [filter, setFilter] = useState<string>('');

    const [domains, setDomains] = useState<Array<MetaDataDomain>>([]);

    const [domainIdentifier, setDomainIdentifier] = useState<string | null>(null);

    const [objectIdentifier, setObjectIdentifier] = useState<string | null>(null);

    const [connectorDType, setConnectorDType] = useState<ConnectorDatabaseType | null>(null);

    const [connectorDataSource, setConnectorDataSource] = useState<ConnectorDataSource | null>(null);

    const navigate = useNavigate();

    const refresh = async () => {
        let { data: dataSources } = await dsFind(0, DATASOURCE_CLASS_IDENTIFIER, {});
        if (dataSources) {
            setData(dataSources);
            if (dataSources && dataSources.length > 0) {
                props.onDataSourceSelected(dataSources[0]);
            }
        }
    };
    useEffect(() => {
        refresh();
    }, [props.version]);

    useEffect(() => {
        if (props.dataSource && props.dataSource.storage_options && props.dataSource.storage_options != '') {
            //获取所有相关的域
            //
            console.log(props.dataSource, props.dataSource.domain_identifiers);
            metaDataGetDomainsByIdentifiers(props.dataSource.domain_identifiers.split(",")).then((res) => {
                setDomains(res);
            });
            let ds: ConnectorDataSource = {
                database_type: props.dataSource.storage_type,
                ...JSON.parse(props.dataSource.storage_options),
                id: props.dataSource.id,
            };
            setConnectorDType(props.dataSource.storage_type as any);
            setConnectorDataSource(ds);
        } else {
            setConnectorDType(null);
            setConnectorDataSource(null);
            setDomains([]);
        }
    }, [props.dataSource]);

    useEffect(() => {
        if (domains && domains.length > 0) {
            //
            if (domainIdentifier === null) {
                setDomainIdentifier(domains[0].identifier);
            } else {
                //判断是否存在
                let exist = false;
                for (let i = 0; i < domains.length; i++) {
                    if (domainIdentifier === domains[i].identifier) {
                        exist = true;
                        break;
                    }
                }
                if (!exist && domainIdentifier !== null) {
                    setDomainIdentifier(null);
                }
            }
        } else {
            setDomainIdentifier(null);
        }
    }, [domains]);

    useEffect(() => {
        props.onDomainSelected && props.onDomainSelected(domainIdentifier);
    }, [domainIdentifier]);

    return (
        <Container style={props.style}>
            <Header>
                <AddButton>
                    <AntdButton
                        icon={<DatabaseOutlined />}
                        onClick={async () => {
                            setDomainMgrOpen(true);
                        }}
                    ></AntdButton>
                </AddButton>
                <Select
                    style={{ flex: 1 }}
                    value={props.dataSource?.identifier}
                    onChange={(value) => {
                        try {
                            if (value) {
                                let res = data.filter(item => item.identifier === value);
                                if (res && res.length > 0) {
                                    props.onDataSourceSelected(res[0]);
                                }
                            } else {
                                props.onDataSourceSelected(null);
                            }
                        } catch (err) {
                            console.log(err);
                        }
                    }}
                    options={data.map((item, index) => {
                        return {
                            value: item.identifier,
                            label: item.title
                        };
                    })} />
                <AddButton>
                    <AntdButton
                        icon={<SettingOutlined />}
                        onClick={async () => {
                            setIsModalOpen(true);
                        }}
                    ></AntdButton>
                </AddButton>
            </Header>
            <Header style={{
                backgroundColor: "#FFF",
                justifyContent: 'center',
                height: '36px'
            }}>
                <Tabs
                    style={{
                    }}
                    defaultActiveKey={props.viewModel}
                    activeKey={props.viewModel}
                    tabBarStyle={{ margin: '0' }} items={[
                        {
                            key: 'storage',
                            label: '存储视图',
                        },
                        {
                            key: 'domain',
                            label: '知识域视图',
                        }
                    ]} onChange={async (key: string) => {
                        console.log(key);
                        props.onViewModelChange && await props.onViewModelChange(key)
                    }} />
            </Header>
            <CollapseContainer>
                {
                    props.viewModel && props.viewModel === 'storage' && <TableList
                        databaseType={connectorDType}
                        dataSource={connectorDataSource}
                        current={table}
                        onClick={async (item: any) => {
                            setTable(item.name);
                            props.onSelected && await props.onSelected(item.name, item);
                        }}></TableList>
                }
                {
                    props.viewModel && props.viewModel === 'domain' && <Collapse
                        accordion={true}
                        bordered={false}
                        activeKey={[domainIdentifier]}
                        onChange={async (keys) => {
                            console.log(keys);
                            if (keys && keys.length > 0) {
                                setDomainIdentifier(keys[0]);
                            } else {
                                setDomainIdentifier(null);
                            }
                        }}
                        expandIconPosition={"start"}
                        destroyInactivePanel={false}
                        items={domains.map((domain, index) => {
                            return {
                                key: domain.identifier,
                                label: domain.title,
                                children: <DomainTree key={index}
                                    filter={filter}
                                    onSelect={async (key: string | null, node: CategoryTreeNode | null) => {
                                        props.onSelected && await props.onSelected(key, node);
                                    }} domain={domain}
                                ></DomainTree>,
                                styles: {
                                    body: {
                                        padding: '0'
                                    }
                                },
                                extra: <SettingOutlined
                                    onClick={async (event) => {
                                        props.onDomainSelected && await props.onDomainSelected(domainIdentifier);
                                        event.stopPropagation();
                                    }}
                                />
                            }
                        })}
                    />
                }

            </CollapseContainer>
            <Modal
                styles={{
                    content: {
                        minWidth: '600px',
                        minHeight: '400px'
                    }
                }}
                title="数据源配置"
                footer={false}
                destroyOnClose={true}
                open={isModalOpen}
                onOk={() => {
                    setIsModalOpen(false);
                }} onCancel={() => {
                    setIsModalOpen(false);
                }}>
                <DataSourceConfig item={props.dataSource} onFinish={async () => {
                    //
                    await refresh();
                    setIsModalOpen(false);
                }}></DataSourceConfig>
            </Modal>
            <Drawer
                title="数据源管理"
                onClose={async () => {
                    //刷新
                    await refresh();
                    setDomainMgrOpen(false);
                }}
                width={'calc(100% - 270px)'}
                destroyOnClose={true}
                open={domainMgrOpen}>
                <DataDataSourceTable></DataDataSourceTable>
            </Drawer>
        </Container>
    );
}



interface CategoryTreeNode {
    title: string;
    key: string;
    icon?: any;
    isLeaf?: boolean;
    children: CategoryTreeNode[];
}

const updateTreeData = (list: CategoryTreeNode[], key: React.Key, children: CategoryTreeNode[]): CategoryTreeNode[] =>
    list.map((node) => {
        if (node.key === key) {
            return {
                ...node,
                children,
            };
        }
        if (node.children) {
            return {
                ...node,
                children: updateTreeData(node.children, key, children),
            };
        }
        return node;
    });

interface DomainTreeProps {
    style?: CSSProperties;
    domain: MetaDataDomain;
    filter: string;
    onSelect: (key: string | null, node: CategoryTreeNode | null) => Promise<void>;
}

const DomainTree: React.FC<DomainTreeProps> = (props) => {

    const [treeData, setTreeData] = useState<Array<CategoryTreeNode>>([]);

    const navigate = useNavigate();

    useEffect(() => {
        if (!props.domain || !props.domain.identifier) return;

        dsFind(0, CLASS_CLASS_IDENTIFIER, {
            relations: [{
                conditions: {
                    class_identifier: DOMAIN_CLASS_IDENTIFIER,
                    direction: 'reverse'
                },
                class_conditions: {
                    attributes: [{
                        name: 'identifier',
                        operator: ComparsionOperator.Equal,
                        value: props.domain.identifier
                    }]
                }
            }]
        }).then((objs) => {
            setTreeData(objs.data.map((objItem, index) => {
                return {
                    title: objItem.title,
                    key: objItem.identifier,
                    icon: <TableOutlined />,
                    isLeaf: true,
                    children: []
                };
            }));
        });
    }, [props.domain]);

    return (
        <TreeContainer style={props.style}>
            <Tree
                showIcon={true}
                showLine={true}
                treeData={treeData.filter(item => item.title?.indexOf(props.filter) >= 0)}
                defaultExpandAll={true}
                onSelect={async (selectedKeys, e: { selected: boolean, selectedNodes, node, event }) => {
                    console.log(selectedKeys, e);
                    if (selectedKeys && selectedKeys.length > 0) {
                        props.onSelect(selectedKeys[0] + '', e.node ? e.node : null);
                    } else {
                        props.onSelect(null, null);
                    }
                }}
            />
        </TreeContainer>
    );
}


const Container = styled.div`
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
`;

const Header = styled.div`
    height: 45px;
    width: 100%;
    padding: 0 0px;
    display: flex;
    background-color: #EFEFEF;
    align-items: center;
    justify-content: space-between;
`;

const AddButton = styled.div`
    width: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
`;

const CollapseContainer = styled.div`
    flex: 1;
    width: 100%;
    overflow-y: auto;
    overflow-x: auto;
`;

const TreeContainer = styled.div`
    flex: 1;
    width: 100%;
`;